import unittest

from python import runfiles


class TestPathUtils(unittest.TestCase):
    """Unit tests for the starlark code in pathutils.bzl."""

    def setUp(self):
        filename = runfiles.Create().Rlocation(
            "drake/tools/skylark/pathutils.bzl"
        )
        with open(filename, "r", encoding="utf-8") as f:
            bzl_contents = f.read()
        self.bzl_globals = dict()
        exec(bzl_contents, self.bzl_globals)

    def _remove_prefix(self, path, prefix):
        """Calls the pathutils.bzl function of the same name."""
        expression = f"_remove_prefix({repr(path)}, {repr(prefix)})"
        return eval(expression, self.bzl_globals)

    def test_remove_prefix(self):
        # A list of path, prefix, expected result.
        suite = [
            # Basic literal matching.
            ["a/b", "a", "b"],
            ["a/b/c", "a", "b/c"],
            ["a/b/c", "a/b", "c"],
            ["a/b", "a/b", None],  # Prefix identical to path.
            ["a/b", "a/b/c", None],  # Prefix longer than the path.
            ["b", "a/b/c", None],  # Prefix in the middle of the path.
            # Single glob matching.
            ["a/b", "*", "b"],
            ["a/b/c", "*", "b/c"],
            ["a/b/c", "a/*", "c"],
            ["a/b", "a/*", None],  # The * must match exactly one name.
            ["a/b/c", "*/b", "c"],
            ["b/c", "*/b", None],  # The * must match exactly one name.
            ["a/b/c/d", "a/*/c", "d"],
            ["a/c/d", "a/*/c", None],  # The * must match exactly one name.
            # Two glob matching.
            ["a/b/c", "*/*", "c"],
            ["a/b", "*/*", None],  # Each * must match exactly one name.
            ["a/b/c/d", "a/*/*", "d"],
            ["a/b/c", "a/*/*", None],  # Each * must match exactly one name.
            ["a/b/c/d", "*/*/c", "d"],
            ["a/b/d", "*/*/c", None],  # Each * must match exactly one name.
            # Double glob matching.
            ["a/b/c/d", "**", "d"],
            ["a/b/c/d", "a/b/c/**", "d"],
            ["a/b/c/d", "a/**", "d"],
            ["a/b/c/d", "a/*/**", "d"],
            ["a/b/c/d", "a/**/*", "d"],
            ["a/b/c/d", "**/c", "d"],
            ["a/b/c/d", "a/**/c", "d"],
            ["a/b/c/d", "a/b/**/c", "d"],
            ["a/b/c/d", "**/b", "c/d"],
            ["a/b/c/d", "a/**/b", "c/d"],
            ["a/b/c/d", "**/a/b", "c/d"],
            # Repeated final name (".../c/c") in prefix.
            ["a/b/c/c", "a/**/c", "c"],
        ]
        for path, prefix, expected in suite:
            with self.subTest(path=path, prefix=prefix):
                result = self._remove_prefix(path, prefix)
                self.assertEqual(result, expected)

                result2 = self._remove_prefix(path, prefix + "/")
                self.assertEqual(result2, expected)
